package com.hm.base.auto;

import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;

import lombok.extern.slf4j.Slf4j;

/**
 * @author shishun.wang
 * @date 2018年1月9日 下午3:33:39
 * @version 1.0
 * @describe
 */
@Slf4j
@SuppressWarnings({ "rawtypes", "unchecked" })
public class RedisLock implements AutoCloseable {

	/**
	 * redis数据存活时间
	 */
	private static long SURVIVE_TIME = 5000;

	/**
	 * 心跳检查
	 */
	private static long HEARTBEAT_TIME = 100;

	private RedisTemplate redisTemplate;

	private String lockName;

	public RedisLock(RedisTemplate redisTemplate, String lockName) {
		super();
		this.redisTemplate = redisTemplate;
		this.lockName = lockName;
	}

	public boolean lock() {
		while (true) {
			Boolean exists = redisTemplate.opsForValue().setIfAbsent(lockName, new byte[0]);
			log.info("轮询当前锁【" + lockName + "】是否被释放---->" + exists);
			if (exists) {
				redisTemplate.expire(lockName, SURVIVE_TIME, TimeUnit.SECONDS);
				return true;
			}

			try {
				Thread.sleep(HEARTBEAT_TIME);
			} catch (Exception e) {
				log.error("心跳检查:" + e.getMessage(), e);
			}
		}
	}

	public void unlock() {
		Boolean exists = redisTemplate.opsForValue().setIfAbsent(lockName, new byte[0]);
		if (!exists) {
			redisTemplate.delete(lockName);
		}
	}

	@Override
	public void close() {
		this.unlock();
	}
}
